package com.yicong.ants.utils;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.PopupWindow;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.poisearch.PoiSearch;
import com.cchao.simplelib.LibCore;
import com.cchao.simplelib.core.JsonHelper;
import com.cchao.simplelib.core.Logs;
import com.cchao.simplelib.core.PrefHelper;
import com.cchao.simplelib.core.RxBus;
import com.cchao.simplelib.core.UiHelper;
import com.cchao.simplelib.util.StringHelper;
import com.yicong.ants.Constants;
import com.yicong.ants.R;
import com.yicong.ants.bean.scenic.ScenicDetailBean;
import com.yicong.ants.manager.AppHelper;
import com.yicong.ants.view.CommonPop;

import java.net.URISyntaxException;



/**
 * 地图工具类
 */
public class AmapHelper {
    public static AMapLocation mAMapLocation;
    public static LocationInfo mLocationInfo;
    private static AMapLocationClient locationClient;
    private static AMapLocationClientOption locationOption;
    static int tip_time = 3;

    /**
     * 初始化定位数据
     *
     * @param context
     * @param locationListener
     */
    private static void initLocation(Context context, AMapLocationListener locationListener) throws Exception {
        //初始化client
        AMapLocationClient.updatePrivacyShow(context, true, true);
        AMapLocationClient.updatePrivacyAgree(context, true);
        locationClient = new AMapLocationClient(context.getApplicationContext());
        locationOption = getDefaultOption();
        //设置定位参数
        locationClient.setLocationOption(locationOption);
        // 设置定位监听
        locationClient.setLocationListener(aMapLocation -> {
            if (aMapLocation.getErrorCode() != 0) {
                if (AppHelper.isDebug()) {
                    tip_time--;
                    if (tip_time < 0) {
                        return;
                    }
                    Logs.logEvent(aMapLocation.getErrorInfo());
                }
                return;
            }
            mAMapLocation = aMapLocation;
            wrapLocationInfo();
            RxBus.get().postEvent(Constants.Event.update_address);
            if (locationListener != null) {
                locationListener.onLocationChanged(aMapLocation);
            }
        });
    }

    public static LocationInfo getLocationInfo() {
        if (mLocationInfo == null && StringHelper.isNotEmpty(PrefHelper.getString(Constants.Prefs.Location_Info))) {
            mLocationInfo = JsonHelper.toObject(PrefHelper.getString(Constants.Prefs.Location_Info), LocationInfo.class);
        }
        return mLocationInfo;
    }

    public static void wrapLocationInfo() {
        mLocationInfo = new AmapHelper.LocationInfo();
        mLocationInfo.setLongitude(String.valueOf(mAMapLocation.getLongitude()))
            .setLatitude(String.valueOf(mAMapLocation.getLatitude()))
            .setProvince(mAMapLocation.getProvince())
            .setCity(mAMapLocation.getCity())
            .setDistrict(mAMapLocation.getDistrict())
            .setAd_code(mAMapLocation.getAdCode());

        PrefHelper.putString(Constants.Prefs.Location_Info, JsonHelper.toJson(mLocationInfo));
    }

    public static boolean hasLocationInfo() {
        return mAMapLocation != null && mAMapLocation.getLatitude() != 0;
    }

    private static AMapLocationClientOption getDefaultOption() {
        AMapLocationClientOption mOption = new AMapLocationClientOption();
        mOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);//可选，设置定位模式，可选的模式有高精度、仅设备、仅网络。默认为高精度模式
        mOption.setGpsFirst(false);//可选，设置是否gps优先，只在高精度模式下有效。默认关闭
        mOption.setHttpTimeOut(30000);//可选，设置网络请求超时时间。默认为30秒。在仅设备模式下无效
        mOption.setInterval(2000);//可选，设置定位间隔。默认为2秒
        mOption.setNeedAddress(true);//可选，设置是否返回逆地理地址信息。默认是true
        mOption.setOnceLocation(true);//可选，设置是否单次定位。默认是false
        mOption.setOnceLocationLatest(true);//可选，设置是否等待wifi刷新，默认为false.如果设置为true,会自动变为单次定位，持续定位时不要使用
        AMapLocationClientOption.setLocationProtocol(AMapLocationClientOption.AMapLocationProtocol.HTTP);//可选， 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP
        mOption.setSensorEnable(false);//可选，设置是否使用传感器。默认是false
        mOption.setWifiScan(true); //可选，设置是否开启wifi扫描。默认为true，如果设置为false会同时停止主动刷新，停止以后完全依赖于系统刷新，定位位置可能存在误差
        mOption.setLocationCacheEnable(true); //可选，设置是否使用缓存定位，默认为true
        return mOption;
    }

    /**
     * 开始进行poi搜索
     */
    public static void doSearchQuery(PoiSearch.OnPoiSearchListener onPoiSearchListener) {
        AMapLocationListener listener = location -> {
            wrapLocationInfo();
            String mType = "汽车服务|餐饮服务|购物服务|生活服务|体育休闲服务|住宿服务|风景名胜|政府机构及社会团体|交通设施服务|公司企业|地名地址信息|公共设施";
            // 第一个参数表示搜索字符串，第二个参数表示poi搜索类型，第三个参数表示poi搜索区域（空字符串代表全国）
            PoiSearch.Query query = new PoiSearch.Query("", mType, location.getCity());
            query.setPageSize(50);// 设置每页最多返回多少条 poiitem
            query.setPageNum(1);// 设置查第一页
            if (location.getLatitude() > 0) {
                PoiSearch poiSearch = new PoiSearch(LibCore.getContext(), query);
                poiSearch.setOnPoiSearchListener(onPoiSearchListener);
                //以当前定位的经纬度为准搜索周围5000米范围
                // 设置搜索区域为以lp点为圆心，其周围5000米范围
                poiSearch.setBound(new PoiSearch.SearchBound(new LatLonPoint(location.getLatitude(), location.getLongitude()), 1000, true));
                poiSearch.searchPOIAsyn();// 异步搜索
            }
        };

        if (mAMapLocation == null) {
            AmapHelper.startLocation(LibCore.getContext(), listener);
        } else {
            listener.onLocationChanged(mAMapLocation);
        }
    }

    /**
     * 开启定位
     *
     * @param context
     * @param locationListener
     */
    public static void startLocation(Context context, AMapLocationListener locationListener) {
        try {
            initLocation(context, locationListener);
            locationClient.startLocation();
        } catch (Exception e) {
            Logs.e(e);
        }
        // 启动定位
    }

    /**
     * 停止定位
     */
    public static void stopLocation() {
        // 停止定位
        locationClient.stopLocation();
    }

    /**
     * 销毁定位
     */
    public static void destroyLocation() {
        if (null != locationClient) {
            /**
             * 如果AMapLocationClient是在当前Activity实例化的，
             * 在Activity的onDestroy中一定要执行AMapLocationClient的onDestroy
             */
            locationClient.onDestroy();
            locationClient = null;
            locationOption = null;
        }
    }

    public static void checkLocation(AMapLocationListener runnable) {
        if (mAMapLocation != null && mAMapLocation.getLatitude() != 0) {
            runnable.onLocationChanged(mAMapLocation);
        } else {
            startLocation(LibCore.getContext(), runnable);
        }
    }

    public static PopupWindow showNavigatePop(Context context, ScenicDetailBean scenicDetail) {
        return showNavigatePop(context, scenicDetail.getAddress(), scenicDetail.getLatitude(), scenicDetail.getLongitude());
    }

    public static void navGaoMap(Context context, String lat, String lon, String address) {
        if (!AppUtils.isInstallByread("com.autonavi.minimap")) {
            UiHelper.showToast("没有安装高德地图客户端");
            return;
        }
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_VIEW);
        intent.addCategory(Intent.CATEGORY_DEFAULT);

        //将功能Scheme以URI的方式传入data
            /*Uri uri = Uri.parse("androidamap://navi?sourceApplication=" + UiHelper.getString(R.string.app_name) + "&amp;" +
                "poiname=" + address + "&amp;" +
                "lat=" + lat + "&amp;" +
                "lon=" + lon + "&amp;" +
                "dev=1&amp;" +
                "style=2");*/
        // amapuri://route/plan/?sid=BGVIS1&slat=39.92848272&slon=116.39560823&sname=A&did=BGVIS2&dlat=39.98848272&dlon=116.47560823&dname=B&dev=0&t=0
        Uri uri = Uri.parse("amapuri://route/plan/?dlat=" + lat + "&dlon=" + lon + "&dname=" + address + "&dev=0&t=0");
        intent.setData(uri);
        context.startActivity(intent);
    }

    public static PopupWindow showNavigatePop(Context context, String address, String lat, String lon) {
        View layView = LayoutInflater.from(context).inflate(R.layout.scenic_map_navigate_pop, null);
        PopupWindow mapPopupWindow = new CommonPop.Builder(context).setView(layView)
            .setBackGroundLevel(0.4f)
            .setOutsideTouchable(true)
            .setWidthAndHeight(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
            .create();

        // 高德
        layView.findViewById(R.id.a_map).setOnClickListener(view -> {
            if (!AppUtils.isInstallByread("com.autonavi.minimap")) {
                UiHelper.showToast("没有安装高德地图客户端");
                return;
            }
            Intent intent = null;
//                intent = Intent.getIntent("androidamap://route?sourceApplication=softname&sname=我的位置&dlat="
//                    + lat + "&dlon=" + lon + "&dname=" + address + "&dev=0&m=0&t=1");
            intent = new Intent();
            intent.setAction(Intent.ACTION_VIEW);
            intent.addCategory(Intent.CATEGORY_DEFAULT);

            //将功能Scheme以URI的方式传入data
            /*Uri uri = Uri.parse("androidamap://navi?sourceApplication=" + UiHelper.getString(R.string.app_name) + "&amp;" +
                "poiname=" + address + "&amp;" +
                "lat=" + lat + "&amp;" +
                "lon=" + lon + "&amp;" +
                "dev=1&amp;" +
                "style=2");*/
            // amapuri://route/plan/?sid=BGVIS1&slat=39.92848272&slon=116.39560823&sname=A&did=BGVIS2&dlat=39.98848272&dlon=116.47560823&dname=B&dev=0&t=0
            Uri uri = Uri.parse("amapuri://route/plan/?dlat=" + lat + "&dlon=" + lon + "&dname=" + address + "&dev=0&t=0");
            intent.setData(uri);

            Logs.logEvent("amap route :" + uri.toString());
            Logs.e("amap route :" + uri.toString());

            //启动该页面即可
            context.startActivity(intent);
            mapPopupWindow.dismiss();
        });
        // 百度地图
        layView.findViewById(R.id.bai_du_map).setOnClickListener(view -> {
            Intent intent = null;
            try {
                intent = Intent.getIntent("intent://map/direction?origin=我的位置&destination="
                    + address
                    + "&mode=driving&src=yourCompanyName|yourAppName#Intent;scheme=bdapp;package=com.baidu.BaiduMap;end");

            } catch (URISyntaxException e) {
                Logs.logException(e);
            }
            if (AppUtils.isInstallByread("com.baidu.BaiduMap")) {
                context.startActivity(intent);
            } else {
                UiHelper.showToast("没有安装百度地图客户端");
            }
            mapPopupWindow.dismiss();
        });
        return mapPopupWindow;
    }

    
    public static class LocationInfo {
        String latitude;
        String longitude;
        String city;
        String province;
        String district;
        String ad_code;

        public LocationInfo() {
        }

        public String getLatitude() {
            return this.latitude;
        }

        public String getLongitude() {
            return this.longitude;
        }

        public String getCity() {
            return this.city;
        }

        public String getProvince() {
            return this.province;
        }

        public String getDistrict() {
            return this.district;
        }

        public String getAd_code() {
            return this.ad_code;
        }

        public LocationInfo setLatitude(String latitude) {
            this.latitude = latitude;
            return this;
        }

        public LocationInfo setLongitude(String longitude) {
            this.longitude = longitude;
            return this;
        }

        public LocationInfo setCity(String city) {
            this.city = city;
            return this;
        }

        public LocationInfo setProvince(String province) {
            this.province = province;
            return this;
        }

        public LocationInfo setDistrict(String district) {
            this.district = district;
            return this;
        }

        public LocationInfo setAd_code(String ad_code) {
            this.ad_code = ad_code;
            return this;
        }

        public boolean equals(final Object o) {
            if (o == this) return true;
            if (!(o instanceof LocationInfo)) return false;
            final LocationInfo other = (LocationInfo) o;
            if (!other.canEqual((Object) this)) return false;
            final Object this$latitude = this.getLatitude();
            final Object other$latitude = other.getLatitude();
            if (this$latitude == null ? other$latitude != null : !this$latitude.equals(other$latitude))
                return false;
            final Object this$longitude = this.getLongitude();
            final Object other$longitude = other.getLongitude();
            if (this$longitude == null ? other$longitude != null : !this$longitude.equals(other$longitude))
                return false;
            final Object this$city = this.getCity();
            final Object other$city = other.getCity();
            if (this$city == null ? other$city != null : !this$city.equals(other$city))
                return false;
            final Object this$province = this.getProvince();
            final Object other$province = other.getProvince();
            if (this$province == null ? other$province != null : !this$province.equals(other$province))
                return false;
            final Object this$district = this.getDistrict();
            final Object other$district = other.getDistrict();
            if (this$district == null ? other$district != null : !this$district.equals(other$district))
                return false;
            final Object this$ad_code = this.getAd_code();
            final Object other$ad_code = other.getAd_code();
            if (this$ad_code == null ? other$ad_code != null : !this$ad_code.equals(other$ad_code))
                return false;
            return true;
        }

        protected boolean canEqual(final Object other) {
            return other instanceof LocationInfo;
        }

        public int hashCode() {
            final int PRIME = 59;
            int result = 1;
            final Object $latitude = this.getLatitude();
            result = result * PRIME + ($latitude == null ? 43 : $latitude.hashCode());
            final Object $longitude = this.getLongitude();
            result = result * PRIME + ($longitude == null ? 43 : $longitude.hashCode());
            final Object $city = this.getCity();
            result = result * PRIME + ($city == null ? 43 : $city.hashCode());
            final Object $province = this.getProvince();
            result = result * PRIME + ($province == null ? 43 : $province.hashCode());
            final Object $district = this.getDistrict();
            result = result * PRIME + ($district == null ? 43 : $district.hashCode());
            final Object $ad_code = this.getAd_code();
            result = result * PRIME + ($ad_code == null ? 43 : $ad_code.hashCode());
            return result;
        }

        public String toString() {
            return "AmapHelper.LocationInfo(latitude=" + this.getLatitude() + ", longitude=" + this.getLongitude() + ", city=" + this.getCity() + ", province=" + this.getProvince() + ", district=" + this.getDistrict() + ", ad_code=" + this.getAd_code() + ")";
        }
        /*
        String latitude = String.valueOf(mAMapLocation.getLatitude());
        String longitude = String.valueOf(mAMapLocation.getLongitude());
        String city = mAMapLocation.getCity();
        String province = mAMapLocation.getProvince();
        String country = mAMapLocation.getCountry();
        String district = mAMapLocation.getDistrict();
        String ad_code = mAMapLocation.getAdCode();*/
    }
}
